﻿using System;
using System.Net.Mail;
using System.Net;

namespace Framework.Common
{

    /// <summary>
    /// mailHelper is a helper class that takes the System.Net.Mail library
    /// and provides a simple library for anyone to use.
    /// </summary>
    public class MailHelper
    {
        #region public static members
        /// <summary>
        /// The status of the mail being sent using the async method
        /// </summary>
        public static string MailStatus = String.Empty;

        /// <summary>
        /// Notifies the calling application of the email status
        /// </summary>
        public static event EventHandler NotifyCaller;

        #endregion

        #region members

        private readonly SmtpClient _mailClient;
        public MailMessage MailMessage { get; set; }
        private MailAddress _mailFromAddress;

        #endregion

        #region events

        /// <summary>
        /// Notifies the calling application about the status of the email being sent
        /// </summary>
        static void OnNotifyCaller()
        {
            if (NotifyCaller != null)
            {
                NotifyCaller(MailStatus, EventArgs.Empty);
            }
        }


        static void MailClient_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            var token = (string)e.UserState;

            if (e.Cancelled)
            {
                MailStatus = token + " Send canceled.";
            }
            if (e.Error != null)
            {
                MailStatus = "Error on " + token + ": " + e.Error;
            }
            else
            {
                MailStatus = token + " mail sent.";
            }

            OnNotifyCaller();
        }
        #endregion

        #region constructor

        public MailHelper()
        {
            _mailClient = new SmtpClient();
            MailMessage = new MailMessage();
        }
        #endregion

        #region methods

        public MailHelper Step1_SmtpServer(string smtpClientHost, int port = 0)
        {
            _mailClient.Host = smtpClientHost;
            if (port > 0)
                _mailClient.Port = port;
            return this;
        }

        public MailHelper Step2_Authorize(String username, String password)
        {
            if (!string.IsNullOrWhiteSpace(username))
            {
                var credentials = new NetworkCredential(username, password);
                _mailClient.Credentials = credentials;
            }
            return this;
        }

        public MailHelper Step3_MailContent(string subject, string body, bool isHtml = true)
        {
            if (!subject.IsBlank())
            {
                MailMessage.Subject = subject;
            }
            if (!body.IsBlank())
            {
                MailMessage.Body = body;
            }
            MailMessage.IsBodyHtml = isHtml;
            return this;
        }

        public MailHelper Step4_To(params string[] receivers)
        {
            if (receivers != null)
            {
                foreach (var to in receivers)
                {
                    if (!to.IsBlank())
                        MailMessage.To.Add(to);
                }
            }
            return this;
        }

        public MailHelper Step5_CC(params string[] receivers)
        {
            if (receivers != null)
            {
                foreach (var to in receivers)
                {
                    if (!to.IsBlank())
                        MailMessage.CC.Add(to);
                }
            }
            return this;
        }

        public MailHelper Step6_BCC(params string[] receivers)
        {
            if (receivers != null)
            {
                foreach (var to in receivers)
                {
                    if (!to.IsBlank())
                        MailMessage.Bcc.Add(to);
                }
            }
            return this;
        }

        public MailHelper Step6_FromAddress(string mfa)
        {
            if (!string.IsNullOrWhiteSpace(mfa))
            {
                _mailFromAddress = new MailAddress(mfa);
                MailMessage.From = _mailFromAddress;
            }
            return this;
        }


        public MailHelper Step7_Attachment(string path)
        {
            if (!path.IsBlank())
            {
                var attachData = new Attachment(path);
                MailMessage.Attachments.Add(attachData);
            }
            return this;
        }

        public bool Send(bool asyncEmail = false)
        {
            try
            {
                using (_mailClient)
                {
                    using (MailMessage)
                    {
                        if (asyncEmail)
                        {
                            _mailClient.SendCompleted += MailClient_SendCompleted;
                            _mailClient.SendAsync(MailMessage, MailMessage.To.ToString());
                        }
                        else
                        {
                            _mailClient.Send(MailMessage);
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                LogHelper.Fatal("发送出错", ex);
                return false;
            }
        }


        #endregion

    }
}
